﻿using CloudFranceTriple.WebRole.Controllers;
using CloudFranceTriple.WebRole.Models;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using System;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

//See https://github.com/lfoust/AccountControllerTests/blob/master/src/SampleWebApp/SampleWebApp.UnitTests/AccountControllerTests.cs#L76

namespace CloudFranceTriple.Tests.Controllers
{
    [TestClass]
    public class AccountControllerTest : UnitTestBase
    {
        [TestMethod]
        [TestCategory("Account")]
        public void AccountController_Login_Get()
        {
            var returnUrl = "/Home/Index";

            // Arrange
            var controller = new AccountController(base.GetWebSecurity.Object);

            controller.ControllerContext = base.GetControllerContext.Object;

            var context =
                new Mock<HttpContextBase>(MockBehavior.Strict);

            controller.Url =
                new UrlHelper(new RequestContext(context.Object,
                new RouteData()), new RouteCollection());

            // Act
            var result = controller.Login(returnUrl) as ViewResult;

            // Assert
            Assert.IsTrue(result.ViewBag.returnUrl == returnUrl);
        }

        [TestMethod]
        [TestCategory("Account")]
        public void AccountController_Login_Success()
        {
            var returnUrl = "/Home/About";
            var _username = base.Username;
            var _password = base.Password;
            var _rememberMe = base.RememberMe;

            var websecurity = base.GetWebSecurity;

            websecurity.Setup(s => s.Login(_username, _password, _rememberMe)).Returns(true);

            // Arrange
            var controller = new AccountController(websecurity.Object);
            var loginModel = new CloudFranceTriple.WebRole.Models.LoginModel { UserName = _username, Password = _password, RememberMe = _rememberMe };
            controller.ControllerContext = base.GetControllerContext.Object;

            var context =
                new Mock<HttpContextBase>();

            controller.Url =
                new UrlHelper(new RequestContext(context.Object,
                new RouteData()), new RouteCollection());

            // Act
            var result = controller.Login(loginModel, returnUrl) as RedirectResult;

            // Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(returnUrl, result.Url);
        }

        [TestMethod]
        [TestCategory("Account")]
        public void AccountController_Login_Failed()
        {
            var returnUrl = "/Home/About";
            var _username = base.Username;
            var _password = base.Password;
            var _rememberMe = base.RememberMe;

            var websecurity = base.GetWebSecurity;

            websecurity.Setup(s => s.Login(_username, _password, _rememberMe)).Returns(false);

            // Arrange
            var controller = new AccountController(websecurity.Object);
            var loginModel = new CloudFranceTriple.WebRole.Models.LoginModel { UserName = _username, Password = _password, RememberMe = _rememberMe };
            controller.ControllerContext = base.GetControllerContext.Object;

            var context =
                new Mock<HttpContextBase>();

            controller.Url =
                new UrlHelper(new RequestContext(context.Object,
                new RouteData()), new RouteCollection());

            // Act
            var result = controller.Login(loginModel, returnUrl) as ViewResult;

            // Assert
            Assert.IsNotNull(result);
        }

        [TestMethod]
        [TestCategory("Account")]
        public void AccountController_LogOff()
        {
            var _username = base.Username;
            var _password = base.Password;
            var _rememberMe = base.RememberMe;

            // Arrange

            var websecurity = base.GetWebSecurity;

            //websecurity.Setup(s => s.Logout()).Returns(null);

            var controller = new AccountController(websecurity.Object);

            controller.ControllerContext = base.GetControllerContext.Object;

            var context =
                new Mock<HttpContextBase>(MockBehavior.Strict);

            controller.Url =
                new UrlHelper(new RequestContext(context.Object,
                new RouteData()), new RouteCollection());

            // Act
            var result = controller.LogOff() as RedirectToRouteResult;

            // Assert
            Assert.IsNotNull(result);

            websecurity.Verify(s => s.Logout(), Times.Exactly(1));
        }

        [TestMethod]
        [TestCategory("Account")]
        public void AccountController_Register_Get()
        {
            // Arrange
            var controller = new AccountController(base.GetWebSecurity.Object);

            controller.ControllerContext = base.GetControllerContext.Object;

            var context =
                new Mock<HttpContextBase>(MockBehavior.Strict);

            controller.Url =
                new UrlHelper(new RequestContext(context.Object,
                new RouteData()), new RouteCollection());

            // Act
            var result = controller.Register() as ViewResult;

            // Assert
            // est ce que la vue a été créé ?
            Assert.IsNotNull(result);

            // est ce qu'il y a des valeurs par défaut ?
            Assert.IsNotNull(result.Model as RegisterModel);

            //est ce que la liste de choix TimeZone a des valeurs ?
            Assert.IsNotNull(result.ViewBag.TimeZone);
        }

        [TestMethod]
        [TestCategory("Account")]
        public void AccountController_Register_Success()
        {
            // Arrange

            var websecurity = base.GetWebSecurity;

            var controller = new AccountController(websecurity.Object);

            controller.ControllerContext = base.GetControllerContext.Object;

            var context =
                new Mock<HttpContextBase>(MockBehavior.Strict);

            controller.Url =
                new UrlHelper(new RequestContext(context.Object,
                new RouteData()), new RouteCollection());

            var model = new RegisterModel
            {
                Birthday = new DateTime(),
                BottomLabelSignature = null,
                ConfirmPassword = "unittest",
                Password = "unittest",
                Culture = "fr-fr",
                Email = "captainmagic@msn.com",
                ForumMessagePostedCounter = 0,
                Gravatar = "captainmagic@msn.com",
                ImageUrlSignature = null,
                InitialAddressIp = "::1",
                LastAddressIp = "::1",
                LastRequestDate = DateTime.UtcNow,
                Location = "CloudFranceTriple.Tests",
                NavigateUrlSignature = null,
                ShowInBirthdayList = true,
                ShowInNonAdminList = true,
                Theming = "default",
                TimeZone = "Romance Standard Time",
                UpperLabelSignature = null,
                UserName = "NewRegisterTest"
            };

            // Act
            var result = controller.Register(model) as RedirectToRouteResult;

            // Assert
            Assert.IsNotNull(result);
        }
    }
}
